#include <iostream>
#include <vector>
using namespace std;
#include "Lexer.h"
#include "SymTable.h"

// Constructors
Lexer::Lexer() : lexBuf("")
{
	currIndex = 0;
}

Lexer::Lexer(const char *newLexBuf) : lexBuf(newLexBuf)
{
	currIndex = 0;
}

// Getter and Setter for the input string
void Lexer::setLexBuf(const char *newLexBuf)
{
	lexBuf.assign(newLexBuf);
	currIndex = 0;
}

const char* Lexer::getLexBuf(void)
{
	return lexBuf.c_str();
}

// Divide the input string into set of tokens. Returns the token recognized. symTableEntryIndex contains the index into the symbol table.
int Lexer::getLexan(int *symTableEntryIndex)
{
	SymTable *symTable = SymTable::getMyInstance();
	while(1)
	{
		if( '\0' == lexBuf[currIndex] )
			return DONE;
		else if( ( lexBuf[currIndex] == ' ' ) || ( lexBuf[currIndex] == '\t' ) || ( lexBuf[currIndex] == '\n' ) )
		{	
			currIndex++; 
			continue;
		}
		else if( isalpha( lexBuf[currIndex] ) )
		{
			int startIndex = currIndex;
			while( isalnum( lexBuf[currIndex] ) )
				currIndex++;
			const char *lexemme = lexBuf.substr(startIndex, currIndex - startIndex).c_str();
			int index = symTable->lookup( lexemme );
			if( -1 == index )
				index = symTable->insert(lexemme, ID);
			*symTableEntryIndex = index;
			return symTable->tokenForEntryAtIndex(index);
		}
		else if( ( '-' == lexBuf[currIndex] ) && ( '>' == lexBuf[currIndex + 1] ) )
		{ 
			currIndex += 2;
			return IMPLIES;
		}
		else if( '&' == lexBuf[currIndex] )
		{
			currIndex++;
			return AND;	
		} 
		else if( '|' == lexBuf[currIndex] )
		{
			currIndex++;
			return OR;
		}
		else if( '!' == lexBuf[currIndex] )
		{
			currIndex++;
			return NOT;
		}
		else if( '(' == lexBuf[currIndex] )
		{
			currIndex++;
			return OPEN_PAREN;
		}
		else if( ')' == lexBuf[currIndex] )
		{
			currIndex++;
			return CLOSE_PAREN;
		}
		else
		{
			return lexBuf[currIndex];
		}
	}	
}
